package org.yak.core.utils;

import java.io.File;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
/**
 *
 * 包名称： com.yqx.p2p.common.util
 * 类名称：DateUtil<br/>
 * 类描述：日期时间操作类<br/>
 * @author px
 * @version v1.0<br/>
 */
public class DateUtil {

	private static final Logger logger = Logger.getLogger(DateUtil.class);

	private DateUtil() {

	}

	/**
	 * 获得当前时间 String类型
	 * @param strFormat
	 * @return 返回时间类型 yyyy-MM-dd HH:mm:ss
	 */
	public static String nowDate() {
		try {
			Date now = new Date();
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			return format.format(now);
		} catch (Exception e) {
			return "";
		}
	}

	public static String nowDateTime() {
		try {
			Date now = new Date();
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return format.format(now);
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 *
	 * @方法没描述：获取当前时间，时分秒
	 * @author xq
	 * @return
	 */
	public static String nowTime() {
		try {
			Date now = new Date();
			SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
			return format.format(now);
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 获得当前时间年份 String类型
	 * @return String 返回时间类型 yyyy
	 */
	public static String nowDateYear() {
		Date now = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
		String nowtime = dateFormat.format(now);
		return nowtime;
	}

	/**
	 * 获得当前时间月份String类型
	 * @return String 返回时间类型 MM
	 */
	public static String nowDateMonth() {
		Date now = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("MM");
		String nowtime = dateFormat.format(now);
		return nowtime;
	}

	/**
	 * 获得当前时间天String类型
	 * @return String 返回时间类型 dd
	 */
	public static String nowDateDay() {
		Date now = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd");
		String nowtime = dateFormat.format(now);
		return nowtime;
	}

	public static String getAfterDateByStringAndFormat(String strDate,
			String strFormat, String type, int param) {
		try {
			Calendar cd = Calendar.getInstance();
			cd.setTime(getDateByStringAndFormat(strDate, strFormat));
			if ("year".equalsIgnoreCase(type))
				cd.add(1, param);
			else if ("month".equalsIgnoreCase(type))
				cd.add(2, param);
			else if ("day".equalsIgnoreCase(type))
				cd.add(5, param);
			else if ("hour".equalsIgnoreCase(type))
				cd.add(11, param);
			else if ("minute".equalsIgnoreCase(type))
				cd.add(12, param);
			else if ("second".equalsIgnoreCase(type))
				cd.add(13, param);
			SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
			String endRingDateTime = sdf.format(cd.getTime());
			return endRingDateTime;
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 *
	 * @方法没描述：获取日期
	 * @author XQ
	 * @param date
	 * @return
	 */
	public static String getDateTime(Date date) {
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return format.format(date);
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 格式化时间格式
	 * @param strDate
	 * @param strFormat
	 * @return
	 */
	public static final Date getDateByStringAndFormat(String strDate, String strFormat) {
		if (strFormat == null || strFormat.equals(""))
			strFormat = "yyyy-MM-dd HH:mm:ss";
		SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
		try {
			return sdf.parse(strDate);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 根据日期获取星期几
	 * @param strDate
	 * @return
	 */
	public static String getWeek(String strDate){
		Calendar cd = Calendar.getInstance();
		cd.setTime(getDateByStringAndFormat(strDate, "yyyy-MM-dd"));
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
        String week = sdf.format(cd.getTime());
        return week;
    }

	/**
	 * 比较时间大小
	 * @param strDate1
	 * @param strDate2
	 * @return
	 */
	public static int getCompareToParam(String strDate1, String strDate2) {
		if (strDate1.compareTo(strDate2) > 0)
			return 1;
		return strDate1.compareTo(strDate2) >= 0 ? 0 : -1;
	}

	/**
	 * 根据日期获取当前属于多少周
	 * @param date
	 * @return
	 */
	public static int getWeekOfYear(String date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setMinimalDaysInFirstWeek(7);
		c.setTime(getDateByStringAndFormat(date, "yyyy-MM-dd"));
		return c.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 得到某年某周的第一天
	 * @param year
	 * @param week
	 * @return
	 */
	public static String getFirstDayOfWeek(int year, int week) {
		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, 2);
		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, week * 7);
		Date date = getFirstDayOfWeek(cal.getTime());
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(date);
	}

	/**
	 * 取得指定日期所在周的第一天
	 * @param date
	 * @return
	 */
	public static Date getFirstDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday
		return c.getTime();
	}

	/**
	 * 得到某年某周的最后一天
	 * @param year
	 * @param week
	 * @return
	 */
	public static String getLastDayOfWeek(int year, int week) {
		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, 2);
		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, week * 7);
		Date date = getLastDayOfWeek(cal.getTime());
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(date);
	}

	/**
	 * 取得指定日期所在周的最后一天
	 * @param date
	 * @return
	 */
	public static Date getLastDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday
		return c.getTime();
	}

	/**
	 * 根据时间取得年份
	 * @param String date
	 * @return
	 */
	public static int getYear(String date) {
		Calendar c = new GregorianCalendar();
		c.setTime(getDateByStringAndFormat(date, "yyyy"));
		return c.get(Calendar.YEAR);
	}

	/**
	 * 取一年中的周数
	 * @param year
	 * @return
	 */
	public static int getWeeks(int year) {
		int week = 0;
		int days = 365;
		int day = 0;
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {// 判断是否闰年，闰年366天
			days = 366;
		}
		// 得到一年所有天数然后除以7
		day = days % 7;// 得到余下几天
		week = days / 7;// 得到多少周
		return week;
	}

	/**
	 * 计算两个日期之间相差的天数
	 *
	 * @param smdate
	 *            较小的时间
	 * @param bdate
	 *            较大的时间
	 * @return 相差天数
	 * @throws ParseException
	 */
	public static int daysBetween(String smdate, String bdate) {
		long between_days = 0;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar cal = Calendar.getInstance();
			cal.setTime(sdf.parse(smdate));
			long time1 = cal.getTimeInMillis();
			cal.setTime(sdf.parse(bdate));
			long time2 = cal.getTimeInMillis();
			between_days = (time2 - time1) / (1000 * 3600 * 24);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return Integer.parseInt(String.valueOf(between_days));
	}

	/**
	 * 转换当前时间为String类型
	 *
	 * @param strFormat
	 * @return
	 */
	public static String getNowDateByFormat(String strFormat) {
		if (strFormat == null || strFormat.equals(""))
			strFormat = "yyyy-MM-dd HH:mm:ss";
		try {
			Date now = new Date();
			SimpleDateFormat format = new SimpleDateFormat(strFormat);
			return format.format(now);
		} catch (Exception e) {
			return "";
		}
	}

	private static Date getLastDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, -1);
		return cal.getTime();
	}

	/**
	 * 取得上一年月
	 * @return
	 */
	public static String nowDateMonthOn() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
		Date date = new Date();
		return sdf.format(getLastDate(date));
	}

	/**
	 * 计算两个时间之间的相差时间数
	 * @param startTime
	 * 				开始时间
	 * @param endTime
	 * 				结束时间
	 * @param format
	 * 				时间格式
	 * @param str
	 * 				返回类型
	 * @return
	 */
	public static Long dateDiff(String startTime, String endTime,
			String format, String str) {
		// 按照传入的格式生成一个simpledateformate对象
		SimpleDateFormat sd = new SimpleDateFormat(format);
		long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
		long nh = 1000 * 60 * 60;// 一小时的毫秒数
		long nm = 1000 * 60;// 一分钟的毫秒数
		long ns = 1000;// 一秒钟的毫秒数
		long diff;
		long day = 0;
		long hour = 0;
		long min = 0;
		long sec = 0;
		// 获得两个时间的毫秒时间差异
		try {
			diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
			day = diff / nd;// 计算差多少天
			hour = diff % nd / nh + day * 24;// 计算差多少小时
			min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟
			sec = diff % nd % nh % nm / ns;// 计算差多少秒
			// 输出结果
			//System.out.println("时间相差：" + day + "天" + (hour - day * 24) + "小时"+ (min - day * 24 * 60) + "分钟" + sec + "秒。");

		} catch (ParseException e) {
			e.printStackTrace();
		}
		if (str.equalsIgnoreCase("h")) {
			return hour;
		} else if (str.equalsIgnoreCase("s")) {
			return min * 60 + sec;
		} else {
			return min;
		}
	}

	public static String removeOneDay(String nowtime,int dayNum) {
		String add = null;
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			java.util.Date timeNow = df.parse(nowtime);
			Calendar begin=Calendar.getInstance();
			begin.setTime(timeNow);
			begin.add(Calendar.DAY_OF_MONTH,dayNum);
			add = df.format(begin.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return add;
	}

	/**
	 * 当前时间增加天数返回新时间
	 * @param days
	 * 				天数
	 * @return
	 */
	public static String addDays(int days) {
		Date d = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String date = format.format(d);
		//System.out.println("现在的日期是：" + date);

		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.DATE, days);// days为增加的天数，可以改变的
		d = ca.getTime();
		String backTime = format.format(d);
		//System.out.println("增加天数以后的日期：" + backTime);
		return backTime;
	}

	/**
     * 计算两个时间之间相隔秒数
     * @param start  开始时间
     * @param end    结束时间
     * @return
     */
	public static int getIntervalSeconds(String startTime, String endTime) {
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	    	Date start = df.parse(startTime);
	    	Date end = df.parse(endTime);
	        //确保start在end之前
	        if(start.after(end)){
	            Date cal = start;
	            start = end;
	            end = cal;
	        }
	        //分别得到两个时间的毫秒数
	        long sl = start.getTime();
	        long el = end.getTime();

	        long ei = el-sl;
	        //根据毫秒数计算间隔天数
	        return (int)(ei/1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
    }

	// 获取年月日时间戳目录地址
	public static String getYearMonthDayPath(){
		return DateUtil.nowDateYear() + File.separator
				+ DateUtil.nowDateMonth() + File.separator
				+ DateUtil.nowDateDay() + File.separator ;
	}

	/**
	 *
	 * @方法没描述：oracle.sql.TIMESTAMP转为java.sql.TIMESTAMP的方法
	 * @author XQ
	 * @param value
	 * @return
	 */
	public static String getOracleTimestamp(Object value) {
		return getOracleTimestamp(value,"yyyy-MM-dd HH:mm:ss");
	}

	/**
	 *
	 * @方法没描述：oracle.sql.TIMESTAMP转为java.sql.TIMESTAMP的方法
	 * @author XQ
	 * @param value
	 * @param format
	 * @return
	 */
	public static String getOracleTimestamp(Object value,String format) {
	    try {
	    	 Method getter = value.getClass().getDeclaredMethod("getTimeZone");
	    	 TimeZone timeZone =  (TimeZone) getter.invoke(value);
	    	 Calendar calendar = new GregorianCalendar();
	    	 calendar.setTimeZone(timeZone);
	    	 if(StringUtils.isEmpty(format)){
	    		 format = "yyyy-MM-dd HH:mm:ss";
	    	 }
	    	 SimpleDateFormat frt = new SimpleDateFormat(format);
			 String time = frt.format(calendar.getTime());
	    	 return time;
	    } catch (Exception e) {
	    	logger.error("转换oracle.sql.TIMESTAMP日期格式异常",e);
	        return "";
	    }
	}

}
